home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Library / Manuels & Misc / Assembly / AOA.ZIP / CH20 / FAKEKBD.ASM next >
Encoding:
Assembly Source File  |  1994-07-24  |  6.8 KB  |  293 lines

  1.         .xlist
  2.         include     stdlib.a
  3.         includelib    stdlib.lib
  4.         .list
  5.  
  6. cseg        segment    para public 'code'
  7.         assume    ds:nothing
  8.  
  9. ;****************************************************************************
  10. ;
  11. ; PutInATBuffer-
  12. ;
  13. ; The following code sticks the scan code into the AT-class keyboard
  14. ; microcontroller chip and asks it to send the scan code back to us
  15. ; (through the hardware port).
  16. ;
  17. ; The AT keyboard controller:
  18. ;
  19. ; Data port is at I/O address 60h
  20. ; Status port is at I/O address 64h (read only)
  21. ; Command port is at I/O address 64h (write only)
  22. ;
  23. ; The controller responds to the following values sent to the command port:
  24. ;
  25. ; 20h - Read Keyboard Controller's Command Byte (KCCB) and send the data to
  26. ;       the data port (I/O address 60h).
  27. ;
  28. ; 60h - Write KCCB.  The next byte written to I/O address 60h is placed in
  29. ;       the KCCB.  The bits of the KCCB are defined as follows:
  30. ;
  31. ;    bit 7- Reserved, should be a zero
  32. ;    bit 6- IBM industrial computer mode.
  33. ;    bit 5- IBM industrial computer mode.
  34. ;       bit 4- Disable keyboard.
  35. ;       bit 3- Inhibit override.
  36. ;       bit 2- System flag
  37. ;    bit 1- Reserved, should be a zero.
  38. ;    bit 0- Enable output buffer full interrupt.
  39. ;
  40. ; AAh -    Self test
  41. ; ABh -    Interface test
  42. ; ACh - Diagnostic dump
  43. ; ADh - Disable keyboard
  44. ; AEh - Enable keyboard
  45. ; C0h - Read Keyboard Controller input port (equip installed)
  46. ; D0h - Read Keyboard Controller output port
  47. ; D1h - Write Keyboard Controller output port
  48. ; E0h - Read test inputs
  49. ; F0h-FFh - Pulse Output port.
  50. ;
  51. ; The keyboard controller output port is defined as follows:
  52. ;
  53. ;    bit 7 -    Keyboard data (output)
  54. ;    bit 6 - Keyboard clock (output)
  55. ;    bit 5 - Input buffer empty
  56. ;    bit 4 - Output buffer full
  57. ;    bit 3 - undefined
  58. ;    bit 2 - undefined
  59. ;    bit 1 - Gate A20
  60. ;    bit 0 - System reset (0=reset)
  61. ;
  62. ; The keyboard controller input port is defined as follows:
  63. ;
  64. ;    bit 7 - Keyboard inhibit switch (0=inhibited)
  65. ;    bit 6 - Display switch (0=color, 1= mono)
  66. ;    bit 5 - Manufacturing jumper
  67. ;    bit 4 - System board RAM (0=disable 2nd 256K RAM on system board).
  68. ;    bits 0-3 - undefined.
  69. ;
  70. ; The keyboard controller status port (64h) is defined as follows:
  71. ;
  72. ;    bit 1-    Set if input data (60h) not available.
  73. ;    bit 0-  Set if output port (60h) cannot accept data.
  74.  
  75.  
  76.  
  77. PutInATBuffer    proc    near
  78.         assume    ds:nothing
  79.         pushf
  80.         push    ax
  81.         push    bx
  82.         push    cx
  83.         push    dx
  84.  
  85.  
  86.         mov    dl, al            ;Save char to output.
  87.  
  88. ; Wait until the keyboard controller does not contain data before
  89. ; proceeding with shoving stuff down its throat.
  90.  
  91.         xor    cx, cx
  92. WaitWhileFull:    in    al, 64h
  93.         test    al, 1
  94.         loopnz    WaitWhileFull
  95.  
  96.  
  97. ; First things first, let's mask the interrupt controller chip (8259) to
  98. ; tell it to ignore interrupts coming from the keyboard.  However, turn the
  99. ; interrupts on so we properly process interrupts from other sources (this
  100. ; is especially important because we're going to wind up sending a false
  101. ; EOI to the interrupt controller inside the INT 9 BIOS routine).
  102.  
  103.         cli
  104.         in    al, 21h            ;Get current mask
  105.         push    ax            ;Save intr mask
  106.         or    al, 2            ;Mask keyboard interrupt
  107.         out    21h, al
  108.  
  109. ; Transmit the desired scan code to the keyboard controller.  Call this
  110. ; byte the new keyboard controller command (we've turned off the keyboard,
  111. ; so this won't affect anything).
  112. ;
  113. ; The following code tells the keyboard controller to take the next byte
  114. ; sent to it and use this byte as the KCCB:
  115.  
  116.  
  117.         call    WaitToXmit
  118.         mov    al, 60h            ;Write new KCCB command.
  119.         out    64h, al
  120.  
  121. ; Send the scan code as the new KCCB:
  122.  
  123.         call    WaitToXmit
  124.         mov    al, dl
  125.         out    60h, al
  126.  
  127. ; The following code instructs the system to transmit the KCCB (i.e., the
  128. ; scan code) to the system:
  129.  
  130.         call    WaitToXmit
  131.         mov    al, 20h        ;"Send KCCB" command.
  132.         out    64h, al
  133.  
  134.         xor    cx, cx
  135. Wait4OutFull:    in    al, 64h
  136.         test    al, 1
  137.         loopz    Wait4OutFull
  138.  
  139. ; Okay, Send a 45h back as the new KCCB to allow the normal keyboard to work
  140. ; properly.
  141.  
  142.         call    WaitToXmit
  143.         mov    al, 60h
  144.         out    64h, al
  145.  
  146.         call    WaitToXmit
  147.         mov    al, 45h
  148.         out    60h, al
  149.  
  150. ; Okay, execute an INT 9 routine so the BIOS (or whoever) can read the key
  151. ; we just stuffed into the keyboard controller.  Since we've masked INT 9
  152. ; at the interrupt controller, there will be no interrupt coming along from
  153. ; the key we shoved in the buffer.
  154.  
  155. DoInt9:         in    al, 60h            ;Prevents ints from some codes.
  156.         int    9                 ;Simulate hardware kbd int.
  157.  
  158.  
  159. ; Just to be safe, reenable the keyboard:
  160.  
  161.         call    WaitToXmit
  162.         mov    al, 0aeh
  163.         out    64h, al
  164.  
  165. ; Okay, restore the interrupt mask for the keyboard in the 8259a.
  166.  
  167.         pop    ax
  168.         out    21h, al
  169.  
  170.         pop    dx
  171.         pop    cx
  172.         pop    bx
  173.         pop    ax
  174.         popf
  175.         ret
  176. PutInATBuffer    endp
  177.  
  178.  
  179.  
  180. ; WaitToXmit-    Wait until it's okay to send a command byte to the keyboard
  181. ;        controller port.
  182.  
  183. WaitToXmit    proc    near
  184.         push    cx
  185.         push    ax
  186.         xor    cx, cx
  187. TstCmdPortLp:    in    al, 64h
  188.         test    al, 2        ;Check cntrlr input buffer full flag.
  189.         loopnz    TstCmdPortLp
  190.         pop    ax
  191.         pop    cx
  192.         ret
  193. WaitToXmit    endp
  194.  
  195.  
  196.  
  197. ;****************************************************************************
  198. ;
  199. ; PutInPS2Buffer- Like PutInATBuffer, it uses the keyboard controller chip
  200. ;          to return the keycode.  However, PS/2 compatible controllers
  201. ;          have an actual command to return keycodes.
  202.  
  203. PutInPS2Buffer    proc    near
  204.         pushf
  205.         push    ax
  206.         push    bx
  207.         push    cx
  208.         push    dx
  209.  
  210.         mov    dl, al            ;Save char to output.
  211.  
  212. ; Wait until the keyboard controller does not contain data before
  213. ; proceeding with shoving stuff down its throat.
  214.  
  215.         xor    cx, cx
  216. WaitWhileFull:    in    al, 64h
  217.         test    al, 1
  218.         loopnz    WaitWhileFull
  219.  
  220.  
  221. ; The following code tells the keyboard controller to take the next byte
  222. ; sent to it and return it as a scan code.
  223.  
  224.  
  225.         call    WaitToXmit
  226.         mov    al, 0d2h        ;Return scan code command.
  227.         out    64h, al
  228.  
  229. ; Send the scan code:
  230.  
  231.         call    WaitToXmit
  232.         mov    al, dl
  233.         out    60h, al
  234.  
  235.         pop    dx
  236.         pop    cx
  237.         pop    bx
  238.         pop    ax
  239.         popf
  240.         ret
  241. PutInPS2Buffer    endp
  242.  
  243.  
  244. ; Main program - Simulates some keystrokes to demo the above code.
  245.  
  246. Main        proc
  247.  
  248.         mov    ax, cseg
  249.         mov    ds, ax
  250.  
  251.         print
  252.         byte    "Simulating keystrokes via Trace Flag",cr,lf
  253.         byte    "This program places 'DIR' in the keyboard buffer"
  254.         byte    cr,lf,0
  255.  
  256.         mov    al, 20h            ;"D" down scan code
  257.         call    PutInATBuffer
  258.         mov    al, 0a0h        ;"D" up scan code
  259.         call    PutInATBuffer
  260.  
  261.         mov    al, 17h            ;"I" down scan code
  262.         call    PutInATBuffer
  263.         mov    al, 97h            ;"I" up scan code
  264.         call    PutInATBuffer
  265.  
  266.         mov    al, 13h            ;"R" down scan code
  267.         call    PutInATBuffer
  268.         mov    al, 93h            ;"R" up scan code
  269.         call    PutInATBuffer
  270.  
  271.         mov    al, 1Ch            ;Enter down scan code
  272.         call    PutInATBuffer
  273.         mov    al, 9Ch            ;Enter up scan code
  274.         call    PutInATBuffer
  275.  
  276.  
  277.  
  278.         ExitPgm
  279. Main        endp
  280.  
  281.  
  282. cseg        ends
  283.  
  284. sseg        segment    para stack 'stack'
  285. stk        db    1024 dup ("stack   ")
  286. sseg        ends
  287.  
  288. zzzzzzseg    segment    para public 'zzzzzz'
  289. LastBytes    db    16 dup (?)
  290. zzzzzzseg    ends
  291.         end    Main
  292.  
  293.